// *********************************************************
//      Copyright (c) Kosta Gaitanis
//      All rights reserved
//
//      k.gaitanis@gmail.com
//
// *********************************************************

#include "Texture.h"

Texture::Texture(const QString &name, const QImage &image) :
    m_name(name),
    m_textureId(0),
    m_isInitialized(false)
{
    setImage(image);
}

Texture::~Texture()
{
    /* FIXME complete the code */
    // delete the texture from the GPU
    glDeleteTextures(1, &m_textureId);
    /* STOP here */
}

void Texture::setName(const QString &name)
{
    m_name = name;
}

QString Texture::getName() const
{
    return m_name;
}

void Texture::setImage(const QImage &image)
{
    m_image = image;

    if (m_image.isNull()) {
        qDebug() << "null image received for texture";
        return;
    }

    if (m_isInitialized) {
        QImage texture = QGLWidget::convertToGLFormat(m_image);

        /* FIXME complete the code */
        //Tester si QGLWidget::convertToGLFormat reussi ou pas
        if(texture.isNull())
        {
            qWarning("Image is null");
            return;
        }
        // bind this texture
        glBindTexture(GL_TEXTURE_2D, m_textureId);
        // load the new image on the GPU
        glTexImage2D(GL_TEXTURE_2D, 0, 4, texture.width(), texture.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, texture.bits());
        // set up texture parameters :
        //  - select modulate to mix texture with color for shading
        glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
        //  - the texture wraps over at the edges (repeat)
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
        //  - when texture area is small, bilinear filter the original
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        //  - when texture area is large, bilinear filter the original
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
        /* STOP here */
    }
}

void Texture::initializeGL()
{
    if (m_isInitialized) {
        qDebug() << m_name << " is already initialized";
        return;
    }
    if (m_image.isNull()) {
        qDebug() << "no image for texture " << m_name;
        return;
    }

    /* FIXME complete the code */
    // generate a texture ID and store it in m_textureId
    GLuint textures[1];
    glGenTextures(1, textures);
    m_textureId = textures[0];
    /* STOP here */

    m_isInitialized = true;
    // load the image on the gPU
    setImage(m_image);
}

void Texture::paintGL() const
{
    /* FIXME complete the code */
    // enable textures
    glEnable(GL_TEXTURE_2D);
    // bind this texture
    glBindTexture(GL_TEXTURE_2D, m_textureId);
    /* STOP here */
}

QImage Texture::getImage() const
{
    return m_image;
}

GLuint Texture::getTextureId() const
{
    return m_textureId;
}


